﻿#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkSmartPointer.h>
#include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNamedColors.h>
#include <vtkClipPolyData.h>
#include <vtkProperty.h>
#include <vtkPlane.h>

/**
 * using vtkClipPolyData to clip a sphere
 */
int main(int, char *[])
{
    vtkSmartPointer<vtkSphereSource> sphereSource =
        vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetCenter(0.0, 0.0, 0.0);
    sphereSource->SetRadius(5.0);
    sphereSource->Update();


    vtkSmartPointer<vtkPlane> plane =
        vtkSmartPointer<vtkPlane>::New();
    plane->SetOrigin(0, 0, 0);
    plane->SetNormal(0, -1, 0);

    vtkSmartPointer<vtkClipPolyData> clipPolyData =
        vtkSmartPointer<vtkClipPolyData>::New();
    clipPolyData->SetInputConnection(sphereSource->GetOutputPort());
    clipPolyData->SetClipFunction(plane);
    clipPolyData->GenerateClippedOutputOn();
    clipPolyData->Update();

    vtkSmartPointer<vtkPolyDataMapper> mapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(sphereSource->GetOutputPort());

    vtkSmartPointer<vtkActor> actor =
        vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    vtkSmartPointer<vtkPolyDataMapper> outMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    outMapper->SetInputConnection(clipPolyData->GetOutputPort());

    vtkSmartPointer<vtkActor> outActor =
        vtkSmartPointer<vtkActor>::New();
    outActor->SetMapper(outMapper);

    vtkSmartPointer<vtkNamedColors> colors =
        vtkSmartPointer<vtkNamedColors>::New();

    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    renderer->SetBackground(colors->GetColor3d("Slate_grey").GetData());
    renderer->AddActor(actor);
    renderer->SetViewport(0, 0, 0.5, 1);

    vtkSmartPointer<vtkRenderer> outRenderer =
        vtkSmartPointer<vtkRenderer>::New();
    outRenderer->SetBackground(colors->GetColor3d("Slate_blue").GetData());
    outRenderer->AddActor(outActor);
    outRenderer->SetViewport(0.5, 0, 1, 1);

    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->SetSize(600, 300);
    renderWindow->AddRenderer(renderer);
    renderWindow->AddRenderer(outRenderer);

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
        vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    renderWindowInteractor->SetInteractorStyle(style);

    renderWindow->Render();
    renderWindowInteractor->Initialize();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}
